home *** CD-ROM | disk | FTP | other *** search
/ Internet Surfer 2.0 / Internet Surfer 2.0 (Wayzata Technology) (1996).iso / pc / text / mac / faqs.554 < prev    next >
Text File  |  1996-02-12  |  28KB  |  613 lines

  1. Frequently Asked Questions (FAQS);faqs.554
  2.  
  3.  
  4.  
  5. Certain window managers, notably dxwm and olwm, are very picky about having
  6. this done.
  7.  
  8.     If you are using Sun's OpenWindows olwm, you can also add this resource
  9. to your defaults file to use clients that aren't ICCCM-compliant.
  10.     OpenWindows.FocusLenience:       true
  11.  
  12. [mostly courtesy Dave Lemke of NCD and Stuart Marks of Sun]
  13.  
  14. ----------------------------------------------------------------------
  15. Subject: 111)  How do I figure out what window manager is running?
  16.  
  17.     You can't reliably tell; whatever mechanism you could use could be
  18. spoofed in any case.
  19.     For most cases, you shouldn't care which window manager is running, so
  20. long as you do things in an ICCCM-conformant manner. There are some cases in
  21. which particular window managers are known to do things wrong; checking for
  22. particular hints placed on the window by the window manager so that you can
  23. sidestep the problem may be appropriate in these cases. Alternatively, it may
  24. be appropriate to determine which window manager is running in order to take
  25. advantage of specific *added* features (such as olwm's push-pin menus) in order
  26. to give your program *added* functionality. Beware of usurping the window
  27. manager's functions by providing that functionality even when it is missing;
  28. this surely leads to future compatibility problems.
  29.  
  30. ----------------------------------------------------------------------
  31. Subject: 112)  Is there a skeleton X program available?
  32.     
  33.     There is no general framework such as the TransSkel program for the
  34. Macintosh which handles lots of the odds and ends and overhead of development
  35. under a window system and which can be used as a platform for additional
  36. development. In X, the problem is typically solved by using an interactive
  37. application builder tool or by using cut&paste on existing X applications. Good
  38. applications which you might look to manipulate when you want to "test just
  39. this one little thing" include contrib/clients/xskel, a simple R4 program that
  40. puts up a window and allows sketching in it and offers a starting point for
  41. quick hacks, the Xaw examples in the examples/ directory in the R3 and R4
  42. distributions, and the Xlib "Hello World" example in the R3 doc/HelloWorld and
  43. R4 doc/tutorials/HelloWorld; an updated version of this program which uses R4
  44. Xlib calls and current ICCCM conventions was posted in 2/90 to comp.windows.x
  45. by Glenn Widener of Tektronix.     [3/90]
  46.  
  47.     In addition, a sample Xt program (for Xaw or Xm) by Rainer Klute
  48. showing how to open multiple displays and how to catch a broken display
  49. connection is available on export.lcs.mit.edu in contrib/mdisp.tar.Z. [4/92]
  50.  
  51. ----------------------------------------------------------------------
  52. Subject: 113)  Why does XtGetValues not work for me (sic)?
  53.  
  54.     The XtGetValues interface for retrieving resources from a widget is
  55. sensitive to the type of variable. Your code may be doing something like this:
  56.     {
  57.     Arg args[3];
  58.     int i;
  59.     int sensitive;        /* oops; wrong data type */
  60.     i=0;
  61.     XtSetArg (args[i], XtNsensitive, &sensitive); i++;
  62.     XtGetValues(widget, args, i );
  63.     ...
  64.     }
  65.  
  66. But XtNsensitive is a Boolean, which on most machines is a single byte;
  67. declaring the variable "sensitive" as Boolean works properly. This problem
  68. comes up often when using particular toolkits that redefine the Xt types
  69. Dimension and Position; code that assumes they are int will have similar
  70. problems if those types are actually short. In general: you are safe if you
  71. use the actual type of the resource, as it appears in the widget's man page.
  72. [11/90]
  73.  
  74. ----------------------------------------------------------------------
  75. Subject: 114)  Why don't XtConfigureWidget/XtResizeWidget/XtMoveWidget work?
  76.  
  77.     You're probably trying to use these functions from application code.
  78. They should be used only internally to widgets; these functions are for a
  79. parent widget to change the geometry of its children. Other promising
  80. functions, XtMakeGeometryRequest() and XtMakeResizeRequest(), are also for use
  81. only by widgets, in this case by a child to request a change from its parent.
  82.     The only way for your application to request a geometry change for a
  83. widget is to issue an XtSetValues call setting some of the geometry resources.
  84. Although this will result in the widget-internal functions' being called, your
  85. application code must use the standard XtSetValues interface or risk the
  86. widgets' data becoming corrupted.
  87.     [The Xlib calls XMoveWindow() and XResizeWindow() should similarly be
  88. avoided; they shouldn't be used to change XtNx, XtNy, XtNwidth, or XtNheight.]
  89.  
  90. ----------------------------------------------------------------------
  91. Subject: 115)  Why isn't there an XtReparentWidget call like XReparentWindow?
  92.  
  93.     Although there are various details of the current implementation of
  94. the Xt internals which make reparenting difficult, the major reason that no
  95. such call exists is that it remains undefined what the set of resources for
  96. the "new" widget should be. Resources are typically set based on the location
  97. in the instance hierarchy; what resources should change if the instance moves?
  98. What should happen to the widget's children? And by the time such semantics are
  99. defined, there would probably be little advantage over destroying the old
  100. widget and creating a new widget in the correct location with the desired
  101. resources, as setting the resources correctly is the majority of work in
  102. creating a new widget.
  103.  
  104.     Note that reparenting is possible in the OI toolkit.
  105.  
  106. ----------------------------------------------------------------------
  107. Subject: 116)  I'm writing a widget and can't use a float as a resource value.
  108.  
  109. Float resources are not portable; the size of the value may be larger than
  110. the size of an XtPointer. Try using a pointer to a float instead; the Xaw
  111. Scrollbar float resources are handled in this way.
  112.  
  113. ----------------------------------------------------------------------
  114. Subject: 117)  Is this a memory leak in the X11R4 XtDestroyWidget()?!
  115.  
  116. Yes. This is the "unofficial" fix-19 for the X11R4 Destroy.c:
  117.  
  118. *** Destroy.c.1.37    Thu Jul 11 15:41:25 1991
  119. --- lib/Xt/Destroy.c    Thu Jul 11 15:42:23 1991
  120. ***************
  121. *** 1,4 ****
  122. --- 1,5 ----
  123.   /* $XConsortium: Destroy.c,v 1.37 90/09/28 10:21:32 swick Exp $ */
  124. + /* Plus unofficial patches in revisions 1.40 and 1.41 */
  125.  
  126.   /***********************************************************
  127.   Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  128. ***************
  129. *** 221,239 ****
  130.        */
  131.  
  132.       int i = 0;
  133. !     DestroyRec* dr = app->destroy_list;
  134.       while (i < app->destroy_count) {
  135.       if (dr->dispatch_level >= dispatch_level)  {
  136.           Widget w = dr->widget;
  137.           if (--app->destroy_count)
  138.           bcopy( (char*)(dr+1), (char*)dr,
  139. !                app->destroy_count*sizeof(DestroyRec)
  140.                 );
  141.           XtPhase2Destroy(w);
  142.       }
  143.       else {
  144.           i++;
  145. -         dr++;
  146.       }
  147.       }
  148.   }
  149. --- 222,245 ----
  150.        */
  151.  
  152.       int i = 0;
  153. !     DestroyRec* dr;
  154.       while (i < app->destroy_count) {
  155. +
  156. +     /* XtPhase2Destroy can result in calls to XtDestroyWidget,
  157. +      * and these could cause app->destroy_list to be reallocated.
  158. +      */
  159. +
  160. +     dr = app->destroy_list + i;
  161.       if (dr->dispatch_level >= dispatch_level)  {
  162.           Widget w = dr->widget;
  163.           if (--app->destroy_count)
  164.           bcopy( (char*)(dr+1), (char*)dr,
  165. !                (app->destroy_count - i) * sizeof(DestroyRec)
  166.                 );
  167.           XtPhase2Destroy(w);
  168.       }
  169.       else {
  170.           i++;
  171.       }
  172.       }
  173.   }
  174.  
  175. [from Donna Converse, converse@expo.lcs.mit.EDU]
  176.  
  177. ----------------------------------------------------------------------
  178. Subject: 118)  Are callbacks guaranteed to be called in the order registered?
  179.  
  180.     Although some books demonstrate that the current implementation of Xt
  181. happens to call callback procedures in the order in which they are registered,
  182. the specification does not guarantee such a sequence, and supplemental
  183. authoritative documents (i.e. the Asente/Swick volume) do say that the order is
  184. undefined.  Because the callback list can be manipulated by both the widget and
  185. the application, Xt cannot guarantee the order of execution.
  186.     In general, the callback procedures should be thought of as operating
  187. independently of one another and should not depend on side-effects of other
  188. callbacks operating; if a seqence is needed, then the single callback to be
  189. registered can explicitly call other functions necessary.
  190.  
  191. [4/92; thanks to converse@expo.lcs.mit.edu]
  192.  
  193. ----------------------------------------------------------------------
  194. Subject: 119)  Why doesn't XtDestroyWidget() actually destroy the widget?
  195.  
  196.     XtDestroyWidget() operates in two passes, in order to avoid leaving
  197. dangling data structures; the function-call marks the widget, which is not
  198. actually destroyed until your program returns to its event-loop.
  199.  
  200. ----------------------------------------------------------------------
  201. Subject: 120)  How do I query the user synchronously using Xt?
  202.     
  203.     It is possible to have code which looks like this trivial callback,
  204. which has a clear flow of control. The calls to AskUser() block until answer
  205. is set to one of the valid values. If it is not a "yes" answer, the code drops
  206. out of the callback and back to an event-processing loop:
  207.  
  208.     void quit(Widget w, XtPointer client, XtPointer call)
  209.     {
  210.         int             answer;
  211.         answer = AskUser(w, "Really Quit?");
  212.         if (RET_YES == answer)
  213.             {
  214.             answer = AskUser(w, "Are You Really Positive?");
  215.             if (RET_YES == answer)
  216.                 exit(0);
  217.                 }
  218.     }
  219.  
  220.     A more realistic example might ask whether to create a file or whether
  221. to overwrite it.
  222.     This is accomplished by entering a second event-processing loop and
  223. waiting until the user answers the question; the answer is returned to the
  224. calling function. That function AskUser() looks something like this, where the
  225. Motif can be replaced with widget-set-specific code to create some sort of
  226. dialog-box displaying the question string and buttons for "OK", "Cancel" and
  227. "Help" or equivalents:
  228.  
  229.   int AskUser(w, string)
  230.         Widget          w;
  231.         char           *string;
  232.   {
  233.         int             answer=RET_NONE;    /* some not-used marker */
  234.         Widget          dialog;            /* could cache&carry, but ...*/
  235.         Arg             args[3];
  236.         int             n = 0;
  237.         XtAppContext    context;
  238.  
  239.         n=0;
  240.         XtSetArg(args[n], XmNmessageString, XmStringCreateLtoR(string,
  241.                 XmSTRING_DEFAULT_CHARSET)); n++;
  242.         XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++;
  243.         dialog = XmCreateQuestionDialog(XtParent(w), string, args, n);
  244.         XtAddCallback(dialog, XmNokCallback, response, &answer);
  245.         XtAddCallback(dialog, XmNcancelCallback, response, &answer);
  246.         XtAddCallback(dialog, XmNhelpCallback, response, &answer);
  247.         XtManageChild(dialog);
  248.  
  249.         context = XtWidgetToApplicationContext (w);
  250.         while (answer == RET_NONE || XtAppPending(context)) {
  251.                 XtAppProcessEvent (context, XtIMAll);
  252.         }
  253.         XtDestroyWidget(dialog);  /* blow away the dialog box and shell */
  254.         return answer;
  255.   }
  256.  
  257.     The dialog supports three buttons, which are set to call the same
  258. function when tickled by the user.  The variable answer is set when the user
  259. finally selects one of those choices:
  260.  
  261.   void response(w, client, call)
  262.         Widget          w;
  263.         XtPointer client;
  264.         XtPointer call;
  265.   {
  266.   int *answer = (int *) client;
  267.   XmAnyCallbackStruct *reason = (XmAnyCallbackStruct *) call;
  268.         switch (reason->reason) {
  269.         case XmCR_OK:
  270.                 *answer = RET_YES;    /* some #define value */
  271.                 break;
  272.         case XmCR_CANCEL:
  273.                 *answer = RET_NO;
  274.         break;
  275.         case XmCR_HELP:
  276.                 *answer = RET_HELP;
  277.                 break;
  278.         default:
  279.                 return;
  280.         }
  281. }
  282.  
  283. and the code unwraps back to the point at which an answer was needed and
  284. continues from there.
  285.  
  286. [Thanks to Dan Heller (argv@sun.com); further code is in Dan's R3/contrib
  287. WidgetWrap library. 2/91]
  288.  
  289. ----------------------------------------------------------------------
  290. Subject: 121)  How do I determine the name of an existing widget?
  291. I have a widget ID and need to know what the name of that widget is.
  292.  
  293.     Users of R4 and later are best off using the XtName() function, which
  294. will work on both widgets and non-widget objects.
  295.  
  296.     If you are still using R3, you can use this simple bit of code to do
  297. what you want. Note that it depends on the widget's internal data structures
  298. and is not necessarily portable to future versions of Xt, including R4.
  299.  
  300.     #include <X11/CoreP.h>
  301.     #include <X11/Xresource.h>
  302.     String XtName (widget)
  303.     Widget widget;    /* WILL work with non-widget objects */
  304.     {
  305.     return XrmNameToString(widget->core.xrm_name);
  306.     }
  307.  
  308. [7/90; modified with suggestion by Larry Rogers (larry@boris.webo.dg.com) 9/91]
  309.  
  310. ----------------------------------------------------------------------
  311. Subject: 122)  What widget is appropriate to use as a drawing canvas?
  312.  
  313.     Some widget sets have a widget particularly for this purpose -- a
  314. WorkSpace or DrawingArea which doesn't display anything but lets your Xt
  315. application know when it has been re-exposed, resized, and when it has received
  316. user key and mouse input.
  317.     The best thing to do for other widget sets -- including the Athena set
  318. -- is to create or obtain such a widget; this is preferable to drawing into a
  319. core widget and grabbing events with XtAddEventHandler(), which loses a number
  320. of benefits of Xt and encapsulation of the functionality .  At least one
  321. version has been posted to comp.sources.x (name???). The publicly-available
  322. programs xball and xpic include other versions. And the Athena Widget manual
  323. (mit/doc/Xaw/Template in the R5 distribution) includes a tutorial and source
  324. code to a simple widget which is suitable for use.
  325.  
  326. ----------------------------------------------------------------------
  327. Subject: 123)  Why do I get a BadDrawable error drawing to XtWindow(widget)?
  328. I'm doing this in order to get a window into which I can do Xlib graphics
  329. within my Xt-based program:
  330.  
  331. > canvas = XtCreateManagedWidget ( ...,widgetClass,...) /* drawing area */
  332. > ...
  333. > window = XtWindow(canvas);    /* get the window associated with the widget */
  334. > ...
  335. > XDrawLine (...,window,...);    /* produces error */
  336.  
  337.     The window associated with the widget is created as a part of the
  338. realization of the widget.  Using a window id of NULL ("no window") could
  339. create the error that you describe.  It is necessary to call XtRealizeWidget()
  340. before attempting to use the window associated with a widget.
  341.     Note that the window will be created after the XtRealizeWidget() call,
  342. but that the server may not have actually mapped it yet, so you should also
  343. wait for an Expose event on the window before drawing into it.
  344.  
  345. ----------------------------------------------------------------------
  346. Subject: 124)  Why do I get a BadMatch error when calling XGetImage?
  347.  
  348. The BadMatch error can occur if the specified rectangle goes off the edge of
  349. the screen. If you don't want to catch the error and deal with it, you can take
  350. the following steps to avoid the error:
  351.  
  352. 1) Make a pixmap the same size as the rectangle you want to capture.
  353. 2) Clear the pixmap to background using XFillRectangle.
  354. 3) Use XCopyArea to copy the window to the pixmap.
  355. 4) If you get a NoExpose event, the copy was clean. Use XGetImage to grab the
  356. image from the pixmap.
  357. 5) If you get one or more GraphicsExpose events, the copy wasn't clean, and
  358. the x/y/width/height members of the GraphicsExpose event structures tell you
  359. the parts of the pixmap which aren't good.
  360. 6) Get rid of the pixmap; it probably takes a lot of memory.
  361.  
  362. [10/92; thanks to Oliver Jones (oj@pictel.com)]
  363.  
  364. ----------------------------------------------------------------------
  365. Subject: 125)  How can my application tell if it is being run under X?
  366.  
  367.     A number of programs offer X modes but otherwise run in a straight
  368. character-only mode. The easiest way for an application to determine that it is
  369. running on an X display is to attempt to open a connection to the X server:
  370.     
  371.     display = XOpenDisplay(display_name);
  372.     if (display)
  373.         { do X stuff }
  374.     else
  375.         { do curses or something else }
  376. where display_name is either the string specified on the command-line following
  377. -display, by convention, or otherwise is (char*)NULL [in which case
  378. XOpenDisplay uses the value of $DISPLAY, if set].
  379.  
  380. This is superior to simply checking for the existence a -display command-line
  381. argument or checking for $DISPLAY set in the environment, neither of which is
  382. adequate. [5/91]
  383.  
  384. ----------------------------------------------------------------------
  385. Subject: 126)! How do I make a "busy cursor" while my application is computing?
  386. Is it necessary to call XDefineCursor() for every window in my application?
  387.  
  388.     The easiest thing to do is to create a single InputOnly window that is
  389. as large as the largest possible screen; make it a child of your toplevel
  390. window and it will be clipped to that window, so it won't affect any other
  391. application. (It needs to be as big as the largest possible screen in case the
  392. user enlarges the window while it is busy or moves elsewhere within a virtual
  393. desktop.) Substitute "toplevel" with your top-most widget here (similar code
  394. should work for Xlib-only applications; just use your top Window):
  395.  
  396.      unsigned long valuemask;
  397.      XSetWindowAttributes attributes;
  398.  
  399.      /* Ignore device events while the busy cursor is displayed. */
  400.      valuemask = CWDontPropagate | CWCursor;
  401.      attributes.do_not_propagate_mask =  (KeyPressMask | KeyReleaseMask |
  402.          ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
  403.      attributes.cursor = XCreateFontCursor(XtDisplay(toplevel), XC_watch);
  404.  
  405.      /* The window will be as big as the display screen, and clipped by
  406.         its own parent window, so we never have to worry about resizing */
  407.      XCreateWindow(XtDisplay(toplevel), XtWindow(toplevel), 0, 0,
  408.          65535, 65535, (unsigned int) 0, CopyFromParent, InputOnly,
  409.          CopyFromParent, valuemask, &attributes);
  410.  
  411. where the maximum size above could be replaced by the real size of the screen,
  412. particularly to avoid servers which have problems with windows larger than
  413. 32767.
  414.  
  415. When you want to use this busy cursor, map and raise this window; to go back to
  416. normal, unmap it. This will automatically keep you from getting extra mouse
  417. events; depending on precisely how the window manager works, it may or may not
  418. have a similar effect on keystrokes as well.
  419.  
  420. In addition, note also that most of the Xaw widgets support an XtNcursor
  421. resource which can be temporarily reset, should you merely wish to change the
  422. cursor without blocking pointer events.
  423.  
  424. [thanks to Andrew Wason (aw@cellar.bae.bellcore.com), Dan Heller
  425. (argv@sun.com), and mouse@larry.mcrcim.mcgill.edu; 11/90,5/91]
  426.  
  427. ----------------------------------------------------------------------
  428. Subject: 127)  How do I fork without hanging my parent X program?
  429.  
  430.     An X-based application which spawns off other Unix processes which
  431. continue to run after it is closed typically does not vanish until all of its
  432. children are terminated; the children inherit from the parent the open X
  433. connection to the display.
  434.     What you need to do is fork; then, immediately, in the child process,
  435.     close (ConnectionNumber(XtDisplay(widget)));
  436. to close the file-descriptor in the display information. After this do your
  437. exec. You will then be able to exit the parent.
  438.  
  439. [Thanks to Janet Anstett (anstettj@tramp.Colorado.EDU) and Gordon Freedman
  440. (gjf00@duts.ccc.amdahl.com) 2/91]
  441.  
  442. ----------------------------------------------------------------------
  443. Subject: 128)  Can I make Xt or Xlib calls from a signal handler?
  444.  
  445.     No. Xlib and Xt have no mutual exclusion for protecting critical
  446. sections. If your signal handler makes such a call at the wrong time (which
  447. might be while the function you are calling is already executing), it can leave
  448. the library in an inconsistent state. Note that the ANSI C standard points
  449. out that behavior of a signal handler is undefined if the signal handler calls
  450. any function other than signal() itself, so this is not a problem specific to
  451. Xlib and Xt; the POSIX specification mentions other functions which may be
  452. called safely but it may not be assumed that these functions are called by
  453. Xlib or Xt functions.
  454.     You can work around the problem by setting a flag in the interrupt
  455. handler and later checking it with a work procedure or a timer event which
  456. has previously been added.
  457.  
  458.     Note: the article in The X Journal 1:4 and the example in O'Reilly
  459. Volume 6 are in error.
  460.  
  461. [Thanks to Pete Ware (ware@cis.ohio-state.edu) and Donna Converse
  462. (converse@expo.lcs.mit.EDU), 5/92]
  463.  
  464. ----------------------------------------------------------------------
  465. Subject: 129)  What are these "Xlib sequence lost" errors?
  466.  
  467.     You may see these errors if you issue Xlib requests from an Xlib error
  468. handler, or, more likely, if you make calls which generate X requests to Xt or
  469. Xlib from a signal handler, which you shouldn't be doing in any case.
  470.  
  471. ----------------------------------------------------------------------
  472. Subject: 130)  How can my Xt program handle socket, pipe, or file input?
  473.  
  474.     It's very common to need to write an Xt program that can accept input
  475. both from a user via the X connection and from some other file descriptor, but
  476. which operates efficiently and without blocking on either the X connection or
  477. the other file descriptor.
  478.     A solution is use XtAppAddInput(). After you open your file descriptor,
  479. use XtAppAddInput() to register an input handler. The input handler will be
  480. called every time there is something on the file descriptor requiring your
  481. program's attention. Write the input handler like you would any other Xt
  482. callback, so it does its work quickly and returns.  It is important to use only
  483. non-blocking I/O system calls in your input handlers.
  484.     Most input handlers read the file descriptor, although you can have an
  485. input handler write or handle exception conditions if you wish.
  486.     Be careful when you register an input handler to read from a disk file.
  487. You will find that the function is called even when there isn't input pending.
  488. XtAppAddInput() is actually working as it is supposed to. The input handler is
  489. called whenever the file descriptor is READY to be read, not only when there is
  490. new data to be read. A disk file (unlike a pipe or socket) is almost always
  491. ready to be read, however, if only because you can spin back to the beginning
  492. and read data you've read before.  The result is that your function will almost
  493. always be called every time around XtAppMainLoop(). There is a way to get the
  494. type of interaction you are expecting; add this line to the beginning of your
  495. function to test whether there is new data:
  496.          if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) return;
  497. But, because this is called frequently, your application is effectively in a
  498. busy-wait; you may be better off not using XtAppAddInput() and instead setting
  499. a timer and in the timer procedure checking the file for input.
  500.  
  501. [courtesy Dan Heller (argv@ora.com), 8/90; mouse@larry.mcrcim.mcgill.edu 5/91;
  502. Ollie Jones (oj@pictel.com) 6/92]
  503.  
  504. ----------------------------------------------------------------------
  505. Subject: 131)  How do I simulate a button press/release event for a widget?
  506.  
  507.     You can do this using XSendEvent(); it's likely that you're not setting
  508. the window field in the event, which Xt needs in order to match to the widget
  509. which should receive the event.
  510.      If you're sending events to your own application, then you can use
  511. XtDispatchEvent() instead. This is more efficient than XSendEvent() in that you
  512. avoid a round-trip to the server.
  513.     Depending on how well the widget was written, you may be able to call
  514. its action procedures in order to get the effects you want.
  515.  
  516. [courtesy Mark A. Horstman (mh2620@sarek.sbc.com), 11/90]
  517.  
  518. ----------------------------------------------------------------------
  519. Subject: 132)  Why doesn't anything appear when I run this simple program?
  520.  
  521. > ...
  522. > the_window = XCreateSimpleWindow(the_display,
  523. >      root_window,size_hints.x,size_hints.y,
  524. >      size_hints.width,size_hints.height,BORDER_WIDTH,
  525. >      BlackPixel(the_display,the_screen),
  526. >      WhitePixel(the_display,the_screen));
  527. > ...
  528. > XSelectInput(the_display,the_window,ExposureMask|ButtonPressMask|
  529. >     ButtonReleaseMask);
  530. > XMapWindow(the_display,the_window);
  531. > ...
  532. > XDrawLine(the_display,the_window,the_GC,5,5,100,100);
  533. > ...
  534.  
  535.     You are right to map the window before drawing into it. However, the
  536. window is not ready to be drawn into until it actually appears on the screen --
  537. until your application receives an Expose event. Drawing done before that will
  538. generally not appear. You'll see code like this in many programs; this code
  539. would appear after window was created and mapped:
  540.   while (!done)
  541.     {
  542.       XNextEvent(the_display,&the_event);
  543.       switch (the_event.type) {
  544.     case Expose:     /* On expose events, redraw */
  545.         XDrawLine(the_display,the_window,the_GC,5,5,100,100);
  546.         break;
  547.     ...
  548.     }
  549.     }
  550.  
  551.     Note that there is a second problem: some Xlib implementations don't
  552. set up the default graphics context to have correct foreground/background
  553. colors, so this program could previously include this code:
  554.   ...
  555.   the_GC_values.foreground=BlackPixel(the_display,the_screen);    /* e.g. */
  556.   the_GC_values.background=WhitePixel(the_display,the_screen);    /* e.g. */
  557.   the_GC = XCreateGC(the_display,the_window,
  558.                 GCForeground|GCBackground,&the_GC_values);
  559.   ...
  560.  
  561. Note: the code uses BlackPixel and WhitePixel to avoid assuming that 1 is
  562. black and 0 is white or vice-versa.  The relationship between pixels 0 and 1
  563. and the colors black and white is implementation-dependent.  They may be
  564. reversed, or they may not even correspond to black and white at all.
  565.  
  566. Also note that actually using BlackPixel and WhitePixel is usually the wrong
  567. thing to do in a finished program, as it ignores the user's preference for
  568. foreground and background.
  569.  
  570. And also note that you can run into the same situation in an Xt-based program
  571. if you draw into the XtWindow(w) right after it has been realized; it may
  572. not yet have appeared.
  573.  
  574. ----------------------------------------------------------------------
  575. Subject: 133)  What is the difference between a Screen and a screen?
  576.  
  577.     The 'Screen' is an Xlib structure which includes the information about
  578. one of the monitors or virtual monitors which a single X display supports. A
  579. server can support several independent screens. They are numbered unix:0.0,
  580. unix:0.1, unix:0.2, etc; the 'screen' or 'screen_number' is the second digit --
  581. the 0, 1, 2 which can be thought of as an index into the array of available
  582. Screens on this particular Display connection.
  583.     The macros which you can use to obtain information about the particular
  584. Screen on which your application is running typically have two forms -- one
  585. which takes a Screen and one with takes both the Display and the screen_number.
  586.     In Xt-based programs, you typically use XtScreen(widget) to determine
  587. the Screen on which your application is running, if it uses a single screen.
  588.     (Part of the confusion may arise from the fact that some of the macros
  589. which return characteristics of the Screen have "Display" in the names --
  590. XDisplayWidth, XDisplayHeight, etc.)
  591.     
  592. ----------------------------------------------------------------------
  593. Subject: 134)  Can I use C++ with X11? Motif? XView?
  594.     
  595.     The X11R4/5 header files are compatible with C++. The Motif 1.1 header
  596. files are usable as is inside extern "C" {...}. However, the definition of
  597. String in Intrinsic.h can conflict with the libg++ or other String class and
  598. needs to be worked around.
  599.  
  600.     Some other projects which can help:
  601.     WWL, a set of C++ classes by Jean-Daniel Fekete to wrap X Toolkit
  602. widgets, available via anonymous FTP from export.lcs.mit.edu as
  603. contrib/WWL-1.2.tar.Z [7/92] or lri.lri.fr (129.175.15.1) as pub/WWL-1.2.tar.Z.
  604. It works by building a set of C++ classes in parallel to the class tree of the
  605. widgets.
  606.     The C++ InterViews toolkit is obtainable via anonymous FTP from
  607. interviews.stanford.edu. InterViews uses a box/glue model similar to that of
  608. TeX for constructing user interfaces and supports multiple looks on the user
  609. interfaces. Some of its sample applications include a WYSIWIG document editor
  610. (doc), a MacDraw-like drawing program (idraw) and an interface builder (ibuild).
  611.     THINGS,  a class library written at the Rome Air Force Base by the
  612. Strategic Air Command, available as freeware on archive sites.
  613.